﻿using System.Collections.Generic;
using System.Linq;
using Shell.Common;
using Shell.KnowledgeBase;

namespace Shell
{
    public static class Rewriter
    {
        public static IEnumerable<Statement> Reduce(this Statement statement, SyntaxRule rule)
        {
            for (var i = 0; i <= statement.Length - rule.Definition.Length; i++)
            {
                var bindingContext = new BindingContext();

                // Achtung! Здесь важен порядок операндов в унификации, иначе Statement.Resolve может отработать неверно и не подставить переменные из statement в результирующую абстракцию
                // TODO: Исправить это безобразие
                if (UnificationModule.UnifyStatements(statement, rule.Definition, i, bindingContext))
                {
                    yield return new Statement(
                        statement
                            .Take(i)
                            .Concat(rule.Declaration.Resolve(bindingContext).Yield())
                            .Concat(statement.Skip(i + rule.Definition.Length)));
                }
            }
        }

        public static IEnumerable<Statement> Expand(this Statement statement, SyntaxRule rule)
        {
            for (var i = 0; i < statement.Length; i++)
            {
                if (statement[i] is Statement)
                {
                    var bindingContext = new BindingContext();

                    // Achtung! Здесь важен порядок операндов в унификации, иначе Statement.Resolve может отработать неверно и не подставить переменные из statement в результирующую абстракцию
                    // TODO: Исправить это безобразие
                    if (UnificationModule.UnifyStatements(rule.Declaration, (Statement) statement[i], bindingContext))
                    {
                        yield return new Statement(
                            statement
                                .Take(i)
                                .Concat(rule.Definition.Resolve(bindingContext))
                                .Concat(statement.Skip(i + 1)));
                    }
                }
            }
        }
    }
}